#include "media_service.h"
#include "media_diagnosis.h"
#include "media_snap_manager.h"
#include "media_osd.h"
#include "common_config_manager.h"
#include "hal_sys.h"
#include "hal_vi.h"
#include "media_audio_manager.h"
#include "media_video_manager.h"
#include "common_product_definition.h"
#include "media_osd.h"
#include "media_speak.h"

namespace El {
namespace Media {

MediaService &MediaService::GetInstance()
{
    static MediaService instance;
    return instance;
}

bool MediaService::Start()
{
    // 初始化mpp
    MppInit();

    // 开启视频编码
    int32_t channelCount = 1;
    if (!Common::ProductDefinition::GetInstance().GetValue("video_channel_count", channelCount)) {
        EL_ERROR("get video channel count failed");
    }
    int32_t streamsCount = 1;
    if (!Common::ProductDefinition::GetInstance().GetValue("video_stream_count", streamsCount)) {
        EL_ERROR("get video stream count failed");
    }

    for (int32_t i = 0; i < channelCount; ++i) {
        for (int32_t j = 0; j < streamsCount; ++j) {
            Media::VideoStreamManager::GetInstance(i, j).Start(nullptr);
        }
    }

    // 开启音频编码
    MediaAudioManager::GetInstance(0).Start(nullptr);

    // 开启osd
    OSDManager::GetInstance().Start();

    // 开启音频播放
    Speak::GetInstance().Start();

    // 开启调试
    CStreamDiagnosis::GetInstance().Start();

    return true;
}

void MediaService::Stop()
{
    return;
}

bool MediaService::MppInit()
{
    HAL_SENDRV_S stSenDrv;
    memset(&stSenDrv, 0, sizeof(stSenDrv));
    stSenDrv.u8SenNum = 1;
    stSenDrv.stSenDrv[0].u8DrvIdx = HAL_DRV_TYPE_SC4336;
    int32_t ret = Hal_Sys_Init(&stSenDrv);
    if (ret != HAL_SUCCESS) {
        EL_ERROR("Hal_Sys_Init failed, ret:{}", ret);
        return false;
    }

    // 从算法配置中推导 YUV 尺寸（取第一个启用算法的 inputWidth/inputHeight），否则使用默认
    uint32_t yuvW = 1024;
    uint32_t yuvH = 576;
    try {
        auto cfg = Common::ConfigManager::GetInstance().GetConfig("/algo_manager");
        if (cfg.is_object() && cfg.contains("algorithms") && cfg["algorithms"].is_array()) {
            for (const auto &algo : cfg["algorithms"]) {
                bool enabled = algo.value("enabled", false);
                if (!enabled) continue;
                // 取第一个启用的算法的输入尺寸
                yuvW = algo.value("inputWidth", yuvW);
                yuvH = algo.value("inputHeight", yuvH);
                break;
            }
        }
    } catch (...) {
        // 保持默认尺寸
    }

    (void)Hal_Vi_SetAlgoYuvSize(0, yuvW, yuvH);
    ret = Hal_Vi_Start(0);
    if (ret != HAL_SUCCESS) {
        EL_ERROR("Hal_Vi_Start failed, ret:{} (requested yuv={}x{})", ret, yuvW, yuvH);
        return false;
    }

    return true;
}

void MediaService::MppDeinit()
{
    return;
}

} // namespace Media
} // namespace El
